#ifndef __base_type_lkjjwfejiojoiwef93323290i98u9hy7yf43jifejji2efjnvnjv__
#define __base_type_lkjjwfejiojoiwef93323290i98u9hy7yf43jifejji2efjnvnjv__

#include <cassert>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <vector>
#include <list>
#include <memory>
#include <string>
#include <functional>
#include <type_traits>

namespace hude
{
    namespace cio
    {
        /**********************************************************************************************
         * @brief c style in/out
         */
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"
#endif

// #pragma  warning( push ) 
// #pragma  warning( disable: 4267 4319 )
// #endif

        template < typename... _args > inline int printf( const char* fmt, _args&&... args )
        {
            return ::printf( fmt, std::forward< _args >( args )... );
        }

        inline int vprintf( const char* fmt, va_list& args )
        {
            return ::vprintf( fmt, args );
        }

        template < typename... _args > inline int snprintf( char* s, size_t n, const char* fmt, _args&&... args )
        {
            return ::snprintf( s, n, fmt, std::forward< _args >( args )... );
        }

        inline int vsnprintf( char* s, size_t n, const char* fmt, va_list& args )
        {
            return ::vsnprintf( s, n, fmt, args );
        }

        template < typename... _args > inline int fprintf( FILE* fp, const char* fmt, _args&&... args )
        {
            return ::fprintf( fp, fmt, std::forward< _args >( args )... );
        }

        inline int vfprintf( FILE* fp, const char* fmt, va_list& args )
        {
            return ::vfprintf( fp, fmt, args );
        }

// #ifdef _MSC_VER
// #pragma  warning(  pop  ) 
// #endif

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
    } //namespace cio
    
    namespace details_types
    {
        /**********************************************************************************************
         * @brief void_t
         */
        typedef struct void_t {} void_t;

        /**********************************************************************************************
         * @brief byte_t
         */
        typedef unsigned char byte_t;

        /**********************************************************************************************
         * @brief uint_t
         */
        typedef uintptr_t uint_t;

        /**********************************************************************************************
         * @brief buffer_t
         */
        typedef std::vector< byte_t > buffer_t;

        /**********************************************************************************************
         * @brief buffers_t
         */
        typedef std::list< buffer_t > buffers_t;

        /**********************************************************************************************
         * @brief copy
         */
        inline buffer_t& copy( buffer_t& dst, const buffers_t& src )
        {
            size_t siz = 0U;

            for( const buffer_t& b : src )
            {
                siz += b.size();
            }

            dst.resize( siz );
            auto current = dst.begin();

            for( const buffer_t& b : src )
            {
                current = std::copy( b.begin(), b.end(), current );
            }

            return dst;
        }

        inline buffer_t& operator<<( buffer_t& dst, const buffers_t& src ) { return copy( dst, src ); }

        /**********************************************************************************************
         * @brief more
         */
        inline buffer_t& move( buffer_t& dst, buffers_t& src )
        {
            if( src.size() == 1 )
            {
                std::swap( dst, src.back() );
            } else {
                copy( dst, src );
            }

            return dst;
        }

        /**********************************************************************************************
         * @brief merge
         */
        inline buffer_t merge( buffers_t& src ) { buffer_t ret; return move( ret, src ); }
        inline buffer_t merge( const buffers_t& src ) { buffer_t ret; return copy( ret, src ); }
            
        /**********************************************************************************************
         * @brief begin
         */
        inline byte_t* begin( buffer_t& buffer )
        {
            return &( buffer[0] );
        }
            
        /**********************************************************************************************
         * @brief end
         */
        inline byte_t* end( buffer_t& buffer )
        {
            return &( buffer[0] ) + buffer.size();
        }
            
        /**********************************************************************************************
         * @brief cbegin
         */
        inline const byte_t* cbegin( const buffer_t& buffer )
        {
            return &( buffer[0] );
        }
            
        /**********************************************************************************************
         * @brief cend
         */
        inline const byte_t* cend( const buffer_t& buffer )
        {
            return &( buffer[0] ) + buffer.size();
        }

        /**********************************************************************************************
         * @brief from_string_t，从字符串转换指定类型的变量
         */
        template< typename _value > struct from_string_t {};

        template<> struct from_string_t< std::string > { static const std::string& get( const std::string& s ) { return s; } };

        template<> struct from_string_t< int8_t   > { static int8_t   get( const std::string& s ) { return std::strtol  ( s.c_str(), nullptr, 0 ); } };
        template<> struct from_string_t< int16_t  > { static int16_t  get( const std::string& s ) { return std::strtol  ( s.c_str(), nullptr, 0 ); } };
        template<> struct from_string_t< int32_t  > { static int32_t  get( const std::string& s ) { return std::strtol  ( s.c_str(), nullptr, 0 ); } };
        template<> struct from_string_t< int64_t  > { static int64_t  get( const std::string& s ) { return std::strtoll ( s.c_str(), nullptr, 0 ); } };

        template<> struct from_string_t< uint8_t  > { static uint8_t  get( const std::string& s ) { return std::strtoul ( s.c_str(), nullptr, 0 ); } };
        template<> struct from_string_t< uint16_t > { static uint16_t get( const std::string& s ) { return std::strtoul ( s.c_str(), nullptr, 0 ); } };
        template<> struct from_string_t< uint32_t > { static uint32_t get( const std::string& s ) { return std::strtoul ( s.c_str(), nullptr, 0 ); } };
        template<> struct from_string_t< uint64_t > { static uint64_t get( const std::string& s ) { return std::strtoull( s.c_str(), nullptr, 0 ); } };

        template<> struct from_string_t< float    > { static float    get( const std::string& s ) { return std::strtof  ( s.c_str(), nullptr );    } };
        template<> struct from_string_t< double   > { static double   get( const std::string& s ) { return std::strtod  ( s.c_str(), nullptr );    } };

        /**********************************************************************************************
         * @brief 从"k = v"的字符串中提取key和value
         */
        struct _key_value_t
        {
            std::string text_, k_, v_;
            std::string::const_iterator itr_, begin_, end_;

            bool kv( const std::string& s )
            {
                itr_ = begin_ = s.cbegin();
                end_ = s.cend();

                if( s.empty() ) return false;

                auto p = s.find( '=' );

                if( p == s.npos || p == 0 || p == ( s.size() - 1 ) )
                    return false;

                itr_ = begin_ + p;

                k_.assign( begin_, itr_ );
                v_.assign( itr_ + 1, end_ );

                return true;
            }

            _key_value_t( const std::string& t ) : text_( t ) { kv( text_ ); }

            bool valied() const { return itr_ != begin_ && itr_ != end_; }

            operator bool () const { return valied(); }

            const std::string& _k() const { return k_; }
            const std::string& _v() const { return v_; }

            template< typename _type > const _type& key  () const { return from_string_t< _type >::get( _k() ); }
            template< typename _type > const _type& value() const { return from_string_t< _type >::get( _v() ); }
        };

        /**********************************************************************************************
         * @brief 以指定的分割符来分割字符串
         * @details 
         *         static const char* str = "a1,a2,a3,b4,y7,hhhh"; //要分割的字符串
         *         // 指定字符串的地址、长度和分割符等参数进行分割。分割的每个子串（序号、起始位置和结束位置）都回调到指定的函数
         *         spliter_t( str, str + strlen( str ), ",", []( std::size_t idx, const char* b, const char* e ) {
         *             std::string s( b, e );
         *             printf( "item: %s", s.c_str() );
         *         } );
         */
        struct spliter_t
        {
            /**********************************************************************************************
             * @brief 子串回调的类型声明，每个分割到的子串都产生回调事件。该回调将获得子串的序号、起始位置和结束位置
             */
            template< typename _itr >
            using cb_t = std::function< void( std::size_t, _itr, _itr ) >;

            /**********************************************************************************************
             * @brief 内部实现使用类型
             */
            std::size_t count_;

            /**********************************************************************************************
             * @brief 构造函数
             */
            spliter_t()
            {
            }

            /**********************************************************************************************
             * @brief 构造函数
             * @param begin: 被分割字符串地址
             * @param end: 被分割字符串长度
             * @param interval: 分割字符串的间隔符，间隔符可以是多个字符组成
             * @param cb: 指定分割到子串时的回调
             */
            template< typename _itr_in, typename _itr_out >
            spliter_t( _itr_in begin, _itr_in end, const char* interval, cb_t< _itr_out > cb )
            {
                _split( begin, end, interval, cb);
            }

            /**********************************************************************************************
             * @brief 分割一个字符串
             * @param begin: 被分割字符串地址
             * @param end: 被分割字符串长度
             * @param interval: 分割字符串的间隔符，间隔符可以是多个字符组成
             * @param cb: 指定分割到子串时的回调
             * @return 返回分割到的子串总数
             */
            template< typename _itr_in, typename _itr_out >
            size_t operator()( _itr_in begin, _itr_in end, const char* interval, cb_t< _itr_out > cb )
            {
                return _split( begin, end, interval, cb);
            }

            /**********************************************************************************************
             * @brief 查询最后一次分割的子串的总数
             */
            operator size_t () const { return count_; }

            /**********************************************************************************************
             * @brief 分割一个字符串
             * @param begin: 被分割字符串地址
             * @param end: 被分割字符串长度
             * @param interval: 分割字符串的间隔符，间隔符可以是多个字符组成
             * @param cb: 指定分割到子串时的回调
             * @return 返回分割到的子串总数
             */
            template< typename _itr_in, typename _itr_out >
            size_t _split( _itr_in begin, _itr_in end, const char* interval, cb_t< _itr_out > cb )
            {
                const size_t ss = std::strlen( interval );

                count_ = 0;

                _itr_out l = begin;

                if( end - begin > (int)ss )
                {
                    for( _itr_out i = begin; i != ( end - ss ); )
                    {
                        if( _comp( i, i + ss, interval ) )
                        {
                            cb( count_, l, i );

                            i += ss;

                            l = i;

                            ++count_;
                        } else {
                            ++i;
                        }
                    }
                }

                if( l < end )
                {
                    cb( count_, l, end );

                    ++count_;
                }

                return count_;
            }

            /**********************************************************************************************
             * @brief 比较是否处于分割符上
             */
            template< typename _itr >
            bool _comp( _itr begin, _itr end, const char* interval )
            {
                for( ; begin != end; ++begin, ++interval )
                {
                    if( *begin != *interval ) return false;
                }

                return true;
            }
        };

        /**********************************************************************************************
         * @brief format_t
         */
        template< std::size_t _size >
        struct _format_t
        {
            std::string str_;

            _format_t() {}

            template< typename ... _args >
            _format_t( const char* fmt, _args && ... args )
            {
                format( fmt, std::forward< _args >( args ) ... );
            }

            template< typename ... _args >
            int format( const char* fmt, _args && ... args )
            {
                int ret = 0;

                if( _size )
                {
                    str_.resize( _size );
                } else {
                    ret = cio::snprintf( nullptr, 0U, fmt, args ... );
                    if( ret <= 0 ) return ret;
                    str_.resize( ret + 1 );
                }

                ret = cio::snprintf( &(str_[0]), str_.size(), fmt, std::forward< _args >( args ) ... );
                str_.resize( ret );

                return ret;
            }

            template< typename ... _args >
            int operator()( const char* fmt, _args && ... args )
            {
                return format( fmt, std::forward< _args >( args ) ... );
            }

            const char* c_str() const { return str_.c_str(); }

            const std::string& str() const { return str_; }
            std::string& str() { return str_; }

            operator const char*() const { return str_.c_str(); }
            operator const std::string&() const { return str_; }

            char operator[]( int n ) const { return str_[n]; }

            size_t size() const { return str_.size(); }
            size_t length() const { return str_.length(); }

            std::string* operator->() { return &str_; }
            const std::string* operator->() const { return &str_; }
        };

        /**********************************************************************************************
         * @brief any_t
         */
        class any_t
        {
        public:
            template<typename value_type>
            friend value_type& any_cast(const any_t& rhs);

            any_t() : content( nullptr ) {}

            template<typename value_type>
            any_t(const value_type& val) :content(new payload_t<value_type>(val)) {}

            any_t(any_t&& rhs) : content( nullptr )
            {
                content = rhs.content;
                rhs.content = nullptr;
            }

            any_t(const any_t& rhs) : content( nullptr )
            {
                content = rhs.content? rhs.content->clone() : nullptr;
            }

            any_t& operator=(const any_t& rhs)
            {
                delete content;
                content = rhs.content? rhs.content->clone() : nullptr;
                return *this;
            }

            any_t& operator=( any_t&& rhs)
            {
                delete content;
                content = rhs.content;
                rhs.content = nullptr;
                return *this;
            }
            
            ~any_t()
            {
                delete content;
            }

            bool has_value() const
            {
                return content != nullptr;
            }

            void swap( any_t& other )
            {
                auto tmp = content;
                content = other.content;
                other.content = tmp;
            }

            template< typename value_type, typename ... _args >
            typename std::decay< value_type >::type& emplace( _args&& ... args )
            {
                auto p = new payload_t< typename std::decay< value_type >::type >( std::forward< _args >( args) ... );
                delete content;
                content = p;
                return p->val;
            }

            const std::type_info& type() const
            {
                return content == nullptr ? typeid(void) : content->type();
            }

        private:
            struct holder_t
            {
                virtual holder_t* clone() const = 0;
                virtual const std::type_info& type() const = 0;
                virtual ~holder_t() { }
            };

            template<typename value_type>
            struct payload_t : public holder_t
            {
                typedef payload_t<value_type> self;

                template< typename ... _args >
                payload_t( _args&& ... args ) : val( std::forward< _args >( args ) ... ) {}

                payload_t(const value_type& v) :val(v) {}

                payload_t(const self&) = delete;
                self& operator = (const self& rhs) = delete;

                virtual payload_t* clone() const { return new payload_t(val); }

                virtual const std::type_info& type() const { return typeid(val); }

                value_type val;
            };

        private:
            holder_t* content;

        };

        /**********************************************************************************************
         * @brief any_cast
         */
        template <typename value_type>
        value_type& any_cast(const any_t &rhs)
        {
            assert( typeid( value_type ) == rhs.type() );

            return dynamic_cast<any_t::payload_t<value_type> *>(rhs.content)->val;
        }

        /**********************************************************************************************
         * @brief any_cast
         */
        template< typename _base, typename _type >
        struct cloneable_t : public _type
        {
            _base* _clone() const override
            {
                return dynamic_cast< _base* >( new cloneable_t< _base, _type >{ *this } );
            }
        };

        /**********************************************************************************************
         * @brief lnglat_t
         */
        typedef std::tuple< double, double > lnglat_t;
        enum { emGET_LONGITUDE, emGET_LATITUDE };

        /**********************************************************************************************
         * @brief cb_stream_t
         */
        typedef std::function< int( const byte_t*, const byte_t* ) > cb_stream_t;
        
        /**********************************************************************************************
         * @brief cb_buffer_t
         */
        typedef std::function< void( buffer_t& ) > cb_buffer_t;

    } //namespace details_types
    
    /**********************************************************************************************/
    using namespace details_types;
    
    /**********************************************************************************************
     * @brief format_t
     */
    using format_t = details_types::_format_t< 0U >;

    /**********************************************************************************************
     * @brief kv_t
     */
    typedef details_types::_key_value_t kv_t;

} //namespace hude

#endif //__base_type_lkjjwfejiojoiwef93323290i98u9hy7yf43jifejji2efjnvnjv__
